package com.animationsp.acs.action;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.servlet.http.HttpServletRequest;


import com.animationsp.acs.bean.ListDir;
import com.animationsp.acs.bean.ListFile;
import com.animationsp.acs.util.Constant;
import com.animationsp.acs.util.ErrorMap;
import com.animationsp.acs.util.MyActionSupport;
import com.opensymphony.webwork.interceptor.ServletRequestAware;
import com.qiniu.api.auth.digest.Mac;
import com.qiniu.api.config.Config;
import com.qiniu.api.rs.Entry;
import com.qiniu.api.rs.RSClient;
import com.qiniu.api.rsf.ListItem;
import com.qiniu.api.rsf.ListPrefixRet;
import com.qiniu.api.rsf.RSFClient;
import com.qiniu.api.rsf.RSFEofException;

public class ViewFileAction extends MyActionSupport implements ServletRequestAware{
	private String key;
	private String prefix;
	private String orderType;
	private String orderASC;
	
	private HttpServletRequest req;
	
	// output
	private List<ListFile> fileList;
	private Set<ListDir> dirSet;
	private List<String> paths = null; // 当前目录路径
	private int pageSize = Constant.PAGE_SIZE;
	private int pageCount; // 总共有几页
	
	/**
	 * 查看文件列表
	 * @return
	 * @throws Exception
	 */
	public String list() throws Exception {
		if(prefix == null || prefix.length() == 0){
			prefix = "";
		}
		if(orderType == null || orderType.length() == 0){
			orderType = Constant.SORT_KEY;
		}
		if(orderASC == null || orderASC.length() == 0){
			orderASC = Constant.ORDER_ASC;
		}
		System.out.println("prefix: "+ prefix);
		prefix = new String(prefix.getBytes("iso8859-1"),"utf-8"); // tomcat默认编码是iso8859-1，所以收到的是该编码的参数，先转成utf-8	
		System.out.println("prefix: "+ prefix);
		System.out.println("prefix  urlencoded: "+java.net.URLEncoder.encode(prefix, "utf-8"));
		
		Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);

		RSFClient client = new RSFClient(mac);
		String marker = "";

		List<ListItem> tempList = new ArrayList<ListItem>();
		ListPrefixRet ret = null;
		while (true) {
			ret = client.listPrifix(Constant.BUCKET, java.net.URLEncoder.encode(prefix, "utf-8"), marker, 1000);
			if(ret.statusCode/100 != 2){
				System.out.println("statusCode:"+ret.statusCode+" "+"response"+ret.response+" "+"exception:"+ret.exception);
				this.setErr(ErrorMap.ERROR_MAP.get(ret.statusCode));
				break;
			}
			marker = ret.marker;
			tempList.addAll(ret.results);

			if (marker == null || marker.length() == 0 || !ret.ok()) {
				// no more items or error occurs
				break;
			}
		}
		
		if (ret.exception !=null && (ret.exception.getClass() != RSFEofException.class) ) {
            // error handler
        } 
		
		// 把查询出来的结果以ListFile为元素放到一个新的list中
		fileList = new ArrayList<ListFile>();
		dirSet = new TreeSet<ListDir>();
		for(Iterator<ListItem> iter = tempList.iterator();iter.hasNext();){
			ListItem listItem = iter.next();
			String noPreName = listItem.key.replaceFirst(prefix, "");
			int sepIndex = noPreName.indexOf(Constant.SEPARATOR);
			if(sepIndex != -1){ // 是目录
				addFile2Dir(listItem.key,prefix+noPreName.substring(0,sepIndex+1),listItem.putTime);
			}else{ // 是文件
				ListFile listFile = new ListFile();
				listFile.setEndUser(listItem.endUser);
				listFile.setFsize(listItem.fsize);
				listFile.setHash(listItem.hash);
				listFile.setKey(listItem.key);
				listFile.setMimeType(listItem.mimeType);
				listFile.setPutTime(listItem.putTime);
				listFile.setOrderType(orderType);
				listFile.setOrderASC(orderASC);
				fileList.add(listFile);
				System.out.println(listItem.key +listItem.fsize + "Byte " + listItem.mimeType + listItem.endUser + listItem.putTime);
			}
			
			
		}
		
		Collections.sort(fileList);
		
		for(Iterator<ListDir> iter = dirSet.iterator();iter.hasNext();){
			ListDir listItem = iter.next();
			System.out.println("dirSet: "+listItem);
		}
		
		String queryString = req.getQueryString();
		if(queryString == null){
			fromUrl = req.getRequestURL().toString();
		}else{
			fromUrl = req.getRequestURL().append("?").append(req.getQueryString()).toString();
		}
		System.out.println("fromUrl: "+ fromUrl);
		
		// 文件路径的url生成
		if(fileList != null && fileList.size()!= 0){
			int lastSep = fileList.get(0).getKey().lastIndexOf("/");
			if(lastSep != -1){
				String filePath = fileList.get(0).getKey().substring(0, lastSep+1);
				String[] pathArr = filePath.split("/");
				if(pathArr.length != 0){
					paths = new ArrayList<String>();
					for(String p :pathArr){
						paths.add(p);
					}
				}
			}
		}else if(dirSet != null && dirSet.size() != 0){
			String[] pathArr = dirSet.iterator().next().getDirName().split("/");
			if(pathArr.length <= 1){
				paths = null;
			}else{
				paths = new ArrayList<String>();
				for(String p :pathArr){
					paths.add(p);
				}
				paths.remove(paths.size()-1);
			}
		}
		
		pageCount = (int)Math.ceil((dirSet.size() + fileList.size())/(float)pageSize);
		
		return SUCCESS;
	}
	
	/**
	 * 把是这个目录中的文件的key放入到对应的ListDir.containsFiles中
	 * @param key 文件名
	 * @param dirName 目录名
	 * @param putTime 文件上传时间
	 */
	private void addFile2Dir(String key,String dirName,long putTime){
		for(Iterator<ListDir> iter = dirSet.iterator();iter.hasNext();){
			ListDir ld = iter.next();
			if(key.startsWith(ld.getDirName())){
				ld.addFile(key);
				ld.setPutTime(putTime);
				return;
			}
		}
		ListDir listDir = new ListDir(dirName);
		listDir.addFile(key);
		listDir.setOrderType(orderType);
		listDir.setOrderASC(orderASC);
		listDir.setPutTime(putTime);
		dirSet.add(listDir);
	}

	/**
	 * 查看单个文件
	 * 
	 * @return
	 * @throws Exception
	 */
	public String view() throws Exception {
		Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
		RSClient client = new RSClient(mac);
		Entry statRet = client.stat(Constant.BUCKET, "<key>");
		System.out.println(statRet.getFsize() + "Byte " + statRet.getMimeType()+ statRet.getPutTime());
		return SUCCESS;
	}

	public static void main(String[] args) {
		System.out.println(System.getProperty("file.encoding"));
		String text = "大家好";
		System.out.println(text);
		
		Mac mac = new Mac("lQvrG3e4dV9w8szU32Dq0SdkcJMTVIRQ_QjGIZIz", "nygi6Ew2RLw3W0fzhBcjtEXg15_D0nIUgVcnA81l");

		RSFClient client = new RSFClient(mac);
		String marker = "";

		List<ListItem> all = new ArrayList<ListItem>();
		ListPrefixRet ret = null;
		while (true) {
			String p = "";
			try {
				p = java.net.URLEncoder.encode("中", "utf-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			ret = client.listPrifix(Constant.BUCKET, p , marker, 10);
			marker = ret.marker;
			all.addAll(ret.results);

			if (marker == null || marker.length() == 0 || !ret.ok()) {
				// no more items or error occurs
				break;
			}
		}

		if (ret.exception !=null && (ret.exception.getClass() != RSFEofException.class) ) {
            // error handler
        }
		
		for(Iterator<ListItem> iter = all.iterator();iter.hasNext();){
			ListItem listItem = iter.next();

			System.out.println(listItem.key +listItem.fsize + "Byte " + listItem.mimeType + listItem.endUser + listItem.putTime);
		}
	}

	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}

	public String getPrefix() {
		return prefix;
	}

	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}

	public List<ListFile> getFileList() {
		return fileList;
	}

	public void setFileList(List<ListFile> fileList) {
		this.fileList = fileList;
	}

	public Set<ListDir> getDirSet() {
		return dirSet;
	}

	public void setDirSet(Set<ListDir> dirSet) {
		this.dirSet = dirSet;
	}
	
	
	public List<String> getPaths() {
		return paths;
	}

	public void setPaths(List<String> paths) {
		this.paths = paths;
	}

	@Override
	public void setServletRequest(HttpServletRequest arg0) {
		this.req = arg0;
	}

	public String getOrderType() {
		return orderType;
	}

	public void setOrderType(String orderType) {
		this.orderType = orderType;
	}

	public String getOrderASC() {
		return orderASC;
	}

	public void setOrderASC(String orderASC) {
		this.orderASC = orderASC;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getPageCount() {
		return pageCount;
	}

	public void setPageCount(int pageCount) {
		this.pageCount = pageCount;
	}
	
	
}
